import time
import random
import ddddocr
from DrissionPage import ChromiumOptions, Chromium


# 三阶贝塞尔曲线函数
def cubic_bezier(p0, p1, p2, p3, t):
    """计算三阶贝塞尔曲线上的点"""
    x = (1 - t) ** 3 * p0[0] + 3 * (1 - t) ** 2 * t * p1[0] + 3 * (1 - t) * t ** 2 * p2[0] + t ** 3 * p3[0]
    y = (1 - t) ** 3 * p0[1] + 3 * (1 - t) ** 2 * t * p1[1] + 3 * (1 - t) * t ** 2 * p2[1] + t ** 3 * p3[1]
    return (x, y)


# 人类轨迹生成函数
def generate_human_track(start_x, start_y, end_x, end_y):
    """生成人类轨迹点"""
    p0 = (start_x, start_y)
    p3 = (end_x, end_y)

    # 随机生成控制点
    offset_y1 = random.randint(5, 20)
    offset_x1 = random.randint(-5, 5)
    p1 = (start_x + (end_x - start_x) / 3 + offset_x1, start_y - offset_y1)

    offset_y2 = random.randint(5, 15)
    offset_x2 = random.randint(-5, 5)
    p2 = (start_x + (end_x - start_x) * 2 / 3 + offset_x2, start_y + offset_y2)

    # 生成轨迹路径（30个点）
    track_points = []
    for t in [i / 30 for i in range(31)]:
        x, y = cubic_bezier(p0, p1, p2, p3, t)
        track_points.append((int(x), int(y)))

    # 添加微小抖动增加真实性
    for i in range(1, len(track_points) - 1):
        dx = random.randint(-2, 2)
        dy = random.randint(-2, 2)
        track_points[i] = (track_points[i][0] + dx, track_points[i][1] + dy)

    return track_points


option = ChromiumOptions()
# 设置无痕
option.incognito(on_off=True)

tab = Chromium(option).latest_tab


def read_silder(target_bytes, background_bytes):
    det = ddddocr.DdddOcr(det=False, ocr=False, show_ad=False)
    res = det.slide_match(target_bytes, background_bytes)
    return res


# 修改后的drop_slider函数 - 完全符合最新文档
def drop_slider(slider, distance):
    """使用人类轨迹算法拖动滑块"""
    # 获取滑块位置（使用文档推荐的属性）
    slider_rect = slider.rect

    # 根据最新文档获取位置信息
    # rect.location返回元素左上角在整个页面中的坐标 (x, y)
    # rect.size返回元素的大小 (width, height)
    location = slider_rect.location
    size = slider_rect.size

    # 计算滑块中心点坐标
    start_x = location[0] + size[0] / 2
    start_y = location[1] + size[1] / 2

    end_x = start_x + distance
    end_y = start_y

    # 生成人类轨迹
    track = generate_human_track(start_x, start_y, end_x, end_y)
    print(f"开始拖动滑块，距离: {distance}px，轨迹点数: {len(track)}")

    # 按住滑块
    action = tab.actions
    action.hold(slider)
    print("拖动滑块")

    # 沿着轨迹移动
    for point in track:
        tab.actions.move(point[0], point[1])
        time.sleep(random.uniform(0.03, 0.08))

    # 在终点附近添加微小晃动
    for _ in range(3):
        tab.actions.move(end_x + random.randint(-3, 3), end_y + random.randint(-3, 3))
        time.sleep(0.05)

    # 释放滑块
    action.release()
    print("拖动完成")


def init_page():
    # 登录
    tab.get("https://sz.jd.com/sz/view/index/login.html?ReturnUrl=http%3A%2F%2Fsz-online.jd.com%2F")
    tab.wait(2)
    login = tab.ele(".login-btn btn")
    if login:
        login.click()
        print("点击登录按钮")
    name = tab.ele("#loginname")
    if name:
        name.input("555666")
        print("输入账号")
    tab.wait(2)
    passwd = tab.ele("#nloginpwd")
    if passwd:
        passwd.input("777888")
        print("输入密码")
    tab.wait(2)
    submit = tab.ele("#loginsubmit")
    if submit:
        submit.click()
        print("点击提交")
    tab.wait(3)

    # 处理验证码
    try:
        background_img = tab.ele('#main_img', timeout=3)
        slot_img = tab.ele('#slot_img', timeout=3)

        if background_img and slot_img:
            background_content = tab.ele("#main_img").src()
            slot_content = tab.ele("#slot_img").src()
            result = read_silder(slot_content, background_content)

            distance = result['target'][0] + 2
            print(f"验证码识别结果：{result}，滑动距离{distance}")

            slider = tab.ele('.slide_path', timeout=3)
            if slider:
                # 打印滑块位置信息用于调试
                rect = slider.rect
                print(f"滑块位置信息: location={rect.location}, size={rect.size}")

                drop_slider(slider, distance)

                # 等待验证结果
                tab.wait(3)

                if "验证成功" in tab.html or "验证通过" in tab.html:
                    print("验证成功")
                else:
                    print("验证可能失败，请检查")
            else:
                print("未找到滑块元素")
        else:
            print("未找到验证码图片元素")
    except Exception as e:
        print(f"处理验证码时出错: {e}")


if __name__ == '__main__':
    init_page()